import axios from 'axios';
import config from '@/config';
import storage from '@/utils/storage';
import router from '@/router';
const TOKEN_INVALID = 'token认证失败,请重新登陆';
const NETWORK_ERROR = '网络出现异常,请稍后再试';

// 创建axios实例对象，添加全局配置
const service = axios.create({
  baseURL: config.baseApi,
  timeout: 8000,
});

// 请求拦截器
service.interceptors.request.use((req) => {
  if (config.env !== 'dev') {
    req.url = '/api/' + req.url
  }
  const headers = req.headers;
  const { token = '' } = storage.getItem('userInfo') || {};
  if (token === '') {
    return req;
  }
  if (!headers.Authorization) headers.Authorization = `Bearer ${token}`;

  return req;
});

// 响应拦截器
service.interceptors.response.use(
  (res) => {
    /**
     * 注意状态码一共有两个
     * 一为http状态码
     * 二为接口返回状态码
     */
    const { code, result, message } = res.data;
    if (code == 1) {
      return result;
    } else if (code == 401) {
      // 清空用户信息
      storage.clearItem('userInfo');
      // 跳转页面
      router.replace('/login');
      // encodeURIComponent(router.currentRoute.value.fullPath)
      // 返回报错信息
      return Promise.reject(TOKEN_INVALID);
    } else {
      return Promise.reject(message || NETWORK_ERROR);
    }
  },
  (err) => {
    const { status } = err.response || {};
    if (status == 401) {
      // 清空无效用户信息
      storage.clearItem('userInfo');
      // 跳转登录页面
      const fullPath = encodeURIComponent(router.currentRoute.value.fullPath);
      // router.replace(`/login?redirectUrl=${fullPath}`)
      // 跳转需要传参
    }
    return Promise.reject(NETWORK_ERROR);
  }
);

/**
 * 请求核心函数
 * @param {*} options  请求配置
 */

// 请求工具函数
function request(options) {
  // 判断get/post
  options.method = options.method || 'get';
  // 防止有时候写了GET
  if (options.method.toLowerCase() === 'get') {
    // 如果是get就将data直接赋值给params
    // 类型转换
    options.params = options.data;
  }
  if (config.env === 'prod') {
    service.defaults.baseURL = config.baseApi;
  } else if (options.mock) {
    service.defaults.baseURL = config.mockApi;
  } else {
    service.defaults.baseURL = config.mock ? config.mockApi : config.baseApi;
  }

  return service(options);
}

['get', 'post', 'put', 'delete', 'patch'].forEach((item) => {
  request[item] = (url, data, options) => {
    return request({
      url,
      data,
      method: item,
      ...options,
    });
  };
});

export default request;
